using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Data;
using System.Collections;
using GL.GL.Classes;
using System.Drawing;
using HR.Controls;

namespace HR.Controls
{
    public enum eColumnType
    {
        DescriptionType,
        StringType,
        DoubleType,
        DoubleReadOnlyType,
        DateType,
        LookupType,
        LookupFreeType,
        IntergerType,
        ComboIndexType
    }
    public class ExtendedDataGridView:DataGridView
    {
        ToolTip tt = new ToolTip();
        private ExtendedDataGridViewTable m_tbl=new ExtendedDataGridViewTable();
        public ExtendedDataGridView()
        {

            tt.AutomaticDelay = 1;
            tt.ReshowDelay = 1;
            tt.InitialDelay = 1;
            tt.AutoPopDelay = 1;
            tt.ShowAlways = false;
            tt.IsBalloon = true;
            tt.ToolTipIcon = ToolTipIcon.Error;
            tt.ToolTipTitle = "Error";
            //this.EditMode = DataGridViewEditMode.EditProgrammatically;

            this.EditMode = DataGridViewEditMode.EditOnEnter;
            this.AutoSize = true;
            this.AutoSizeColumnsMode= DataGridViewAutoSizeColumnsMode.AllCells;
            this.DefaultCellStyle.Padding  = new Padding(0,0,20,0);
            
        }

        ~ExtendedDataGridView()
        {
            tt.RemoveAll();
            tt.Dispose();
            tt = null;
        }
        
        
        /*
        
        public override bool PreProcessMessage(ref Message msg)
        {
            int WM_KEYDOWN = 0x100;
             int WM_KEYUP  = 0x101;
             int WM_CHAR  = 0x102;
            Keys keyCode = (((Keys)msg.WParam.ToInt32()) & Keys.KeyCode);

        if (msg.Msg == WM_KEYDOWN && keyCode == Keys.Enter)
        {
            int intRow = this.CurrentCell.RowIndex;
            int intCol = this.CurrentCell.ColumnIndex;

            intCol += 1;
            if (intCol == this.ColumnCount)
            {
                intCol = 0;
                intRow += 1;
                if (intRow == this.RowCount)
                    intRow = 0;                
            }
            this.CurrentCell = this[intCol, intRow];
            return true;
        }
            return base.PreProcessMessage(ref msg);
        }
        */



        public void setTable(ExtendedDataGridViewTable tbl)
        {

            m_tbl = tbl;
            foreach (ExtendedDataGridViewColumn col in m_tbl.Columns)
            {

                DataGridViewColumn dcol=null;
                
                switch(col.ColumnType)
                {
                    case eColumnType.LookupType:
                    case eColumnType.LookupFreeType:
                        dcol = new LookupColumn(col.LookupParam);
                        dcol.DefaultCellStyle.NullValue = "";
                        break;
                    case eColumnType.DoubleReadOnlyType:
                    case eColumnType.DoubleType:
                    case eColumnType.IntergerType:
                        dcol = new NumericColumn();
                        if (col.ColumnType == eColumnType.DoubleType)
                            dcol.DefaultCellStyle.Format = "#,###.##";
                        else
                            dcol.DefaultCellStyle.Format = "#,###";
                        dcol.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
                        dcol.DefaultCellStyle.NullValue = 0;
                        dcol.ReadOnly = (col.ColumnType == eColumnType.DoubleReadOnlyType);
                        break;
                    case eColumnType.DateType:
                        dcol = new DateColumn();
                        dcol.DefaultCellStyle.NullValue = DateTime.MinValue;
                        break;
                    case eColumnType.ComboIndexType:
                        DataGridViewComboBoxColumn x = new DataGridViewComboBoxColumn();
                        x.DataSource = col.DescriptionColumn.Split('|');
                        dcol = x;
                        break;
                    default:
                        dcol = new DataGridViewTextBoxColumn();
                        dcol.ReadOnly = (col.ColumnType == eColumnType.DescriptionType);
                        dcol.DefaultCellStyle.NullValue = "";
                        break;
                }

                
                    dcol.Name = col.ColumnName;
                    dcol.HeaderText = col.ColumnTitle;
                    this.Columns.Add(dcol);
                    
            }

            

            //Constants.TidyGrid(this);

        }
        public LookupParameterTextBox getLookupParam(int colindex){
            return ((ExtendedDataGridViewColumn)m_tbl.Columns[colindex]).LookupParam;
        }
        
        protected override void OnCellBeginEdit(DataGridViewCellCancelEventArgs e)
        {
            if (this.ReadOnly)
                e.Cancel = true;
            else
            {
                if (this.CurrentCell is LookupCell)
                    ((LookupCell)this.CurrentCell).LookupParam = ((ExtendedDataGridViewColumn)m_tbl.Columns[e.ColumnIndex]).LookupParam;



                base.OnCellBeginEdit(e);
            }
            //e.Cancel = true;
        }


        protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {

            if((keyData & Keys.Control) == Keys.Control 
                &&
                (keyData & Keys.Delete) == Keys.Delete
               )
            {
                if(this.CurrentRow.Index != this.NewRowIndex)
                    this.Rows.Remove(this.CurrentRow);
                return true;
            }
            return base.ProcessCmdKey(ref msg, keyData);
        }
        
            protected override bool ProcessDialogKey(Keys keyData)
            {
                if (keyData == Keys.Enter)
                {
                    
                    int col = this.CurrentCell.ColumnIndex;
                    int row = this.CurrentCell.RowIndex;
                    Point x = MoveNextColumns(col, col, row);
                    this.CurrentCell=this[x.X,x.Y];
                    return true;
                }
                
                return base.ProcessDialogKey(keyData);
            }

            protected override void OnKeyDown(KeyEventArgs e)
            {
                if (e.KeyData == Keys.Enter)
                {
                    
                    int col = this.CurrentCell.ColumnIndex;
                    int row = this.CurrentCell.RowIndex;
                    Point x = MoveNextColumns(col, col, row);
                    this.CurrentCell=this[x.X,x.Y];
                    e.Handled = true;
                }
                
                base.OnKeyDown(e);
            }

        private Point MoveNextColumns(int startcol, int col, int row)
        {
            if (this.ReadOnly)
                return new Point(col, row);


            ExtendedDataGridViewColumn x = (ExtendedDataGridViewColumn)m_tbl.Columns[col];
            
            if (x.ColumnType == eColumnType.LookupType)
            {
                if (x.LookupParam.SqlDescription.Trim() != "")
                {
                    
                    string csql = x.LookupParam.SqlDescription.Replace("@TEXT", Constants.sqlStr(Constants.IsNull(this[col, row].EditedFormattedValue,"").ToString()));
                    object s = Program.db.executeFirstRowFirstCol(csql);
                    if (s == null)
                    {
                        this.EditingControl.BackColor = Color.LightSalmon;
                        tt.Show("Data tidak valid", this.EditingControl);
                        tt.Show("Data tidak valid", this.EditingControl);
                        return new Point(col, row);
                    }
                    else
                    {
                        tt.RemoveAll();
                        //tt.Hide(this.EditingControl);
                        this.EditingControl.BackColor = Color.PaleGoldenrod;
                    }

                }
            }
                    

            
            col++;            
            if (col >= this.Columns.Count)
            {
                if (row != this.NewRowIndex)
                {
                    row++;
                    col = 0;
                }else{
                    col--;
                }
            }            
            if(((ExtendedDataGridViewColumn)m_tbl.Columns[col]).ColumnType==eColumnType.DescriptionType
                || ((ExtendedDataGridViewColumn)m_tbl.Columns[col]).ColumnType == eColumnType.DoubleReadOnlyType 
                || !this.Columns[col].Visible
                )
                if (col != startcol)
                    return MoveNextColumns(startcol , col, row);
            
            return new Point(col, row);
            
            
        }
        protected override void OnCellValueChanged(DataGridViewCellEventArgs e)
        {
            if (this[e.ColumnIndex,e.RowIndex] is LookupCell)
            {
                if (this[e.ColumnIndex, e.RowIndex].Value != null)
                {
                    ExtendedDataGridViewColumn s = ((ExtendedDataGridViewColumn)m_tbl.Columns[e.ColumnIndex]);
                    if (s.LookupParam!=null && s.DescriptionColumn != null && s.DescriptionColumn != "")
                        this[s.DescriptionColumn, e.RowIndex].Value = Program.db.executeFirstRowFirstCol(s.LookupParam.SqlDescription.Replace("@TEXT", Constants.toSql(this[e.ColumnIndex, e.RowIndex].Value.ToString())), "");
                    //((LookupCell)this[e.ColumnIndex, e.RowIndex]).LookupParam = ((ExtendedDataGridViewColumn)m_tbl.Columns[e.ColumnIndex]).LookupParam;
                }
            }
            base.OnCellValueChanged(e);
        }
        public void CallOnCellValueChanged(DataGridViewCellEventArgs e)
        {
            OnCellValueChanged(e);
        }

        protected override void OnLeave(EventArgs e)
        {
            tt.RemoveAll();
            base.OnLeave(e);
        }

        /*
        protected override void OnEditModeChanged(EventArgs e)
        {
            this.CurrentCell.Value = this.CurrentCell.EditedFormattedValue;
            base.OnEditModeChanged(e);
        }
         * */
        /*
        protected override void OnLostFocus(EventArgs e)
        {
            this.CurrentCell.Value = this.CurrentCell.EditedFormattedValue;
        }
        */

        
        /*
        protected override void OnCellLeave(DataGridViewCellEventArgs e)
        {
            ExtendedDataGridViewColumn x = (ExtendedDataGridViewColumn)m_tbl.Columns[e.ColumnIndex];
            if (x.ColumnType == eColumnType.LookupType)
            {
                if (x.LookupParam.SqlDescription.Trim() != "")
                {

                        string csql = x.LookupParam.SqlDescription.Replace("@TEXT", Constants.sqlStr(this[e.ColumnIndex,e.RowIndex].Value.ToString()));
                        object s = Program.db.executeFirstRowFirstCol(csql);
                        if (s == null)
                        {
                            this.CurrentCell = this[e.ColumnIndex, e.RowIndex];
                            return;
                        }                    
                    
                }
            }
                                
            base.OnCellLeave(e);
        }
        */

    }

    public class ExtendedDataGridViewTable
    {
        public ArrayList Columns= new ArrayList();
        
        public void ColumnsClear()
        {
            Columns.Clear();
        }

        public void ColumnsAdd(ExtendedDataGridViewColumn col)
        {
            Columns.Add(col);
        }
    }

    public class ExtendedDataGridViewColumn
    {
        private string m_column_name;
        private eColumnType m_column_type;
        private string m_column_title;
        private string m_desc_column;
        private LookupParameterTextBox m_lookup_param;

        public string ColumnName { set { m_column_name= value; } get { return m_column_name; } }
        public eColumnType ColumnType{ set { m_column_type= value; } get { return m_column_type; } }
        public string ColumnTitle { set { m_column_title= value; } get { return m_column_title; } }
        public string DescriptionColumn { set { m_desc_column = value; } get { return m_desc_column; } }
        public LookupParameterTextBox LookupParam { set { m_lookup_param= value; } get { return m_lookup_param; } }

        public ExtendedDataGridViewColumn(string p_column_name, eColumnType p_fld_type, string  p_column_title, LookupParameterTextBox lp, string p_desc_column)
        {
            m_column_name = p_column_name;
            m_column_type = p_fld_type;
            if (p_column_title == "")
                m_column_title = m_column_name;
            else
                m_column_title = p_column_title;
            m_column_title = p_column_title;
            m_lookup_param = lp;
            m_desc_column = p_desc_column;
        }

    }



#region LookupColumn
public class LookupColumn : DataGridViewColumn
{
    public LookupColumn() : base() { }
    public LookupColumn(LookupParameterTextBox lp)
        : base(new LookupCell(lp))
    {
    }

    public override DataGridViewCell CellTemplate
    {
        get
        {
            return base.CellTemplate;
        }
        set
        {
            // Ensure that the cell used for the template is a CalendarCell.
            if (value != null &&
                !value.GetType().IsAssignableFrom(typeof(LookupCell)))
            {
                throw new InvalidCastException("Must be a LookupCell");
            }
            base.CellTemplate = value;
        }
    }

    /*
    public LookupParameterTextBox LookupParam
    {
        set { ((LookupCell)CellTemplate).LookupParam = value; }
        get { return ((LookupCell)CellTemplate).LookupParam; }
    }
     * */
}


class LookupCell : DataGridViewTextBoxCell
{
    LookupParameterTextBox lookupParam;

    public LookupCell()
        : base()
    {
    }

    public LookupCell(LookupParameterTextBox lp)
        : base()
    {
        lookupParam = lp;
    }

    public LookupParameterTextBox LookupParam
    {
        set { lookupParam = value; }
        get { return lookupParam; }
    }
    

    public override void InitializeEditingControl(int rowIndex, object
        initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)
    {
        // Set the value of the editing control to the current cell value.
        base.InitializeEditingControl(rowIndex, initialFormattedValue,
            dataGridViewCellStyle);
        LookupEditingControl ctl =
            DataGridView.EditingControl as LookupEditingControl;
        ctl.IsAutoCheckValidation = false;
        ctl.Parameter = lookupParam;
        if (this.Value == null)
            ctl.Text = "";
        else
            ctl.Text = this.Value.ToString();
    }

    public override Type EditType
    {
        get
        {
            // Return the type of the editing contol that CalendarCell uses.
            return typeof(LookupEditingControl);
        }
    }

    public override Type ValueType
    {
        get
        {
            // Return the type of the value that CalendarCell contains.
            return typeof(object);
        }
    }

    public override object DefaultNewRowValue
    {
        get
        {
            // Use the current date and time as the default value.
            return "";
        }
    }
}

class LookupEditingControl : HR.Controls.LookupTextBox, IDataGridViewEditingControl
{
    DataGridView dataGridView;
    private bool valueChanged = false;
    int rowIndex;
    #region IDataGridViewEditingControl Members

    public void ApplyCellStyleToEditingControl(DataGridViewCellStyle dataGridViewCellStyle)
    {
    }

    public DataGridView EditingControlDataGridView { get { return dataGridView; } set { dataGridView = value; } }

    public object EditingControlFormattedValue { get { return this.Text; } set { this.Text = value.ToString(); } }

    public int EditingControlRowIndex { get { return rowIndex; } set { rowIndex = value; } }

    public bool EditingControlValueChanged { get { return valueChanged; } set { valueChanged = value; } }

    public bool EditingControlWantsInputKey(Keys keyData, bool dataGridViewWantsInputKey)
    {
        switch (keyData & Keys.KeyCode)
        {
            case Keys.Left:
            //case Keys.Up:
            //case Keys.Down:
            case Keys.Right:
            case Keys.Home:
            case Keys.End:
            case Keys.OemPeriod:
            case Keys.Decimal:             
            //case Keys.Enter:
            //case Keys.Return:
                //case Keys.PageDown:
                //case Keys.PageUp:
                return true;
            default:
                return false;
        }

    }

    public Cursor EditingPanelCursor
    {
        get { return base.Cursor; }
    }

    public object GetEditingControlFormattedValue(DataGridViewDataErrorContexts context)
    {
        return EditingControlFormattedValue;
    }

    public void PrepareEditingControlForEdit(bool selectAll)
    {
    }

    public bool RepositionEditingControlOnValueChange
    {
        get { return false; }
    }

    #endregion

    protected override void OnTextChanged(EventArgs e)
    {
        valueChanged = true;
        this.EditingControlDataGridView.NotifyCurrentCellDirty(true);
        base.OnTextChanged(e);
    }

}

#endregion

#region CalendarColumn

public class CalendarColumn : DataGridViewColumn
{
    public CalendarColumn() : base(new CalendarCell())
    {
    }

    public override DataGridViewCell CellTemplate
    {
        get
        {
            return base.CellTemplate;
        }
        set
        {
            // Ensure that the cell used for the template is a CalendarCell.
            if (value != null && 
                !value.GetType().IsAssignableFrom(typeof(CalendarCell)))
            {
                throw new InvalidCastException("Must be a CalendarCell");
            }
            base.CellTemplate = value;
        }
    }
}

public class CalendarCell : DataGridViewTextBoxCell
{

    public CalendarCell()
        : base()
    {
        // Use the short date format.
        this.Style.Format = "d";
    }

    public override void InitializeEditingControl(int rowIndex, object 
        initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)
    {
        // Set the value of the editing control to the current cell value.
        base.InitializeEditingControl(rowIndex, initialFormattedValue, 
            dataGridViewCellStyle);
        CalendarEditingControl ctl = 
            DataGridView.EditingControl as CalendarEditingControl;
        ctl.Value = (DateTime)this.Value;
    }

    public override Type EditType
    {
        get
        {
            // Return the type of the editing contol that CalendarCell uses.
            return typeof(CalendarEditingControl);
        }
    }

    public override Type ValueType
    {
        get
        {
            // Return the type of the value that CalendarCell contains.
            return typeof(DateTime);
        }
    }

    public override object DefaultNewRowValue
    {
        get
        {
            // Use the current date and time as the default value.
            return DateTime.Now;
        }
    }
}

class CalendarEditingControl : DateTimePicker, IDataGridViewEditingControl
{
    DataGridView dataGridView;
    private bool valueChanged = false;
    int rowIndex;

    public CalendarEditingControl()
    {
        this.Format = DateTimePickerFormat.Short;
    }

    // Implements the IDataGridViewEditingControl.EditingControlFormattedValue 
    // property.
    public object EditingControlFormattedValue
    {
        get
        {
            return this.Value.ToShortDateString();
        }
        set
        {
            if (value is String)
            {
                this.Value = DateTime.Parse((String)value);
            }
        }
    }

    // Implements the 
    // IDataGridViewEditingControl.GetEditingControlFormattedValue method.
    public object GetEditingControlFormattedValue(
        DataGridViewDataErrorContexts context)
    {
        return EditingControlFormattedValue;
    }

    // Implements the 
    // IDataGridViewEditingControl.ApplyCellStyleToEditingControl method.
    public void ApplyCellStyleToEditingControl(
        DataGridViewCellStyle dataGridViewCellStyle)
    {
        this.Font = dataGridViewCellStyle.Font;
        this.CalendarForeColor = dataGridViewCellStyle.ForeColor;
        this.CalendarMonthBackground = dataGridViewCellStyle.BackColor;
    }

    // Implements the IDataGridViewEditingControl.EditingControlRowIndex 
    // property.
    public int EditingControlRowIndex
    {
        get
        {
            return rowIndex;
        }
        set
        {
            rowIndex = value;
        }
    }

    // Implements the IDataGridViewEditingControl.EditingControlWantsInputKey 
    // method.
    public bool EditingControlWantsInputKey(
        Keys key, bool dataGridViewWantsInputKey)
    {
        // Let the DateTimePicker handle the keys listed.
        switch (key & Keys.KeyCode)
        {
            case Keys.Left:
            case Keys.Up:
            case Keys.Down:
            case Keys.Right:
            case Keys.Home:
            case Keys.End:
            case Keys.PageDown:
            case Keys.PageUp:
                return true;
            default:
                return false;
        }
    }

    // Implements the IDataGridViewEditingControl.PrepareEditingControlForEdit 
    // method.
    public void PrepareEditingControlForEdit(bool selectAll)
    {
        // No preparation needs to be done.
    }

    // Implements the IDataGridViewEditingControl
    // .RepositionEditingControlOnValueChange property.
    public bool RepositionEditingControlOnValueChange
    {
        get
        {
            return false;
        }
    }

    // Implements the IDataGridViewEditingControl
    // .EditingControlDataGridView property.
    public DataGridView EditingControlDataGridView
    {
        get
        {
            return dataGridView;
        }
        set
        {
            dataGridView = value;
        }
    }

    // Implements the IDataGridViewEditingControl
    // .EditingControlValueChanged property.
    public bool EditingControlValueChanged
    {
        get
        {
            return valueChanged;
        }
        set
        {
            valueChanged = value;
        }
    }

    // Implements the IDataGridViewEditingControl
    // .EditingPanelCursor property.
    public Cursor EditingPanelCursor
    {
        get
        {
            return base.Cursor;
        }
    }

    protected override void OnValueChanged(EventArgs eventargs)
    {
        // Notify the DataGridView that the contents of the cell
        // have changed.
        valueChanged = true;
        this.EditingControlDataGridView.NotifyCurrentCellDirty(true);
        base.OnValueChanged(eventargs);
    }
}
#endregion
/*
public class Form1 : Form
{
    private DataGridView dataGridView1 = new DataGridView();

    [STAThreadAttribute()]
    public static void Main()
    {
        Application.Run(new Form1());
    }

    public Form1()
    {
        this.dataGridView1.Dock = DockStyle.Fill;
        this.Controls.Add(this.dataGridView1);
        this.Load += new EventHandler(Form1_Load);
        this.Text = "DataGridView calendar column demo";
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        CalendarColumn col = new CalendarColumn();
        this.dataGridView1.Columns.Add(col);
        this.dataGridView1.RowCount = 5;
        foreach (DataGridViewRow row in this.dataGridView1.Rows)
        {
            row.Cells[0].Value = DateTime.Now;
        }
    }
}

****/

#region datecolumn
public class DateColumn : DataGridViewColumn
{
    public DateColumn()
        : base(new DateCell())
    {
    }

    public override DataGridViewCell CellTemplate
    {
        get
        {
            return base.CellTemplate;
        }
        set
        {
            // Ensure that the cell used for the template is a CalendarCell.
            if (value != null &&
                !value.GetType().IsAssignableFrom(typeof(DateCell)))
            {
                throw new InvalidCastException("Must be a DateCell");
            }
            base.CellTemplate = value;
        }
    }
}

public class DateCell : DataGridViewTextBoxCell
{

    public DateCell()
        : base()
    {
        // Use the short date format.
        
    }

    public override void InitializeEditingControl(int rowIndex, object
        initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)
    {
        // Set the value of the editing control to the current cell value.
        base.InitializeEditingControl(rowIndex, initialFormattedValue,
            dataGridViewCellStyle);
        DateEditingControl ctl =
            DataGridView.EditingControl as DateEditingControl;
        ctl.Text  = this.Value.ToString();
    }

    public override Type EditType
    {
        get
        {
            // Return the type of the editing contol that CalendarCell uses.
            return typeof(DateEditingControl);
        }
    }

    public override Type ValueType
    {
        get
        {
            // Return the type of the value that CalendarCell contains.
            return typeof(object);
        }
    }

    public override object DefaultNewRowValue
    {
        get
        {
            // Use the current date and time as the default value.
            return "00/00/0000";
        }
    }
}

class DateEditingControl : DateTextBox, IDataGridViewEditingControl
{
    DataGridView dataGridView;
    private bool valueChanged = false;
    int rowIndex;

    public DateEditingControl()
    {
        this.MaxLength = 10;
    }

    // Implements the IDataGridViewEditingControl.EditingControlFormattedValue 
    // property.
    public object EditingControlFormattedValue
    {
        get
        {
            return this.Text.Substring(0,10);
        }
        set
        {
            if (value is string)
            {
                this.Text = value.ToString().Substring(0,10);
            }
            else if (value is HrDateTime)
            {
                this.Text= ((HrDateTime)value).DateText;
            }
        }
    }

    // Implements the 
    // IDataGridViewEditingControl.GetEditingControlFormattedValue method.
    public object GetEditingControlFormattedValue(
        DataGridViewDataErrorContexts context)
    {
        return EditingControlFormattedValue;
    }

    // Implements the 
    // IDataGridViewEditingControl.ApplyCellStyleToEditingControl method.
    public void ApplyCellStyleToEditingControl(
        DataGridViewCellStyle dataGridViewCellStyle)
    {
    }

    // Implements the IDataGridViewEditingControl.EditingControlRowIndex 
    // property.
    public int EditingControlRowIndex
    {
        get
        {
            return rowIndex;
        }
        set
        {
            rowIndex = value;
        }
    }

    // Implements the IDataGridViewEditingControl.EditingControlWantsInputKey 
    // method.
    public bool EditingControlWantsInputKey(
        Keys key, bool dataGridViewWantsInputKey)
    {
        // Let the DateTimePicker handle the keys listed.
        switch (key & Keys.KeyCode)
        {
            case Keys.Left:
            case Keys.Up:
            case Keys.Down:
            case Keys.Right:
            case Keys.Home:
            case Keys.End:
            case Keys.PageDown:
            case Keys.PageUp:
            //case Keys.Enter:
            case Keys.Return:
                return true;
            default:
                return false;
        }
    }

    // Implements the IDataGridViewEditingControl.PrepareEditingControlForEdit 
    // method.
    public void PrepareEditingControlForEdit(bool selectAll)
    {
        // No preparation needs to be done.
    }

    // Implements the IDataGridViewEditingControl
    // .RepositionEditingControlOnValueChange property.
    public bool RepositionEditingControlOnValueChange
    {
        get
        {
            return false;
        }
    }

    // Implements the IDataGridViewEditingControl
    // .EditingControlDataGridView property.
    public DataGridView EditingControlDataGridView
    {
        get
        {
            return dataGridView;
        }
        set
        {
            dataGridView = value;
        }
    }

    // Implements the IDataGridViewEditingControl
    // .EditingControlValueChanged property.
    public bool EditingControlValueChanged
    {
        get
        {
            return valueChanged;
        }
        set
        {
            valueChanged = value;
        }
    }

    // Implements the IDataGridViewEditingControl
    // .EditingPanelCursor property.
    public Cursor EditingPanelCursor
    {
        get
        {
            return base.Cursor;
        }
    }

    /*
  protected override void OnValueChanged(EventArgs eventargs)
  {
      // Notify the DataGridView that the contents of the cell
      // have changed.
      valueChanged = true;
      this.EditingControlDataGridView.NotifyCurrentCellDirty(true);
      base.OnValueChanged(eventargs);
  }
    
   
 
    */
  protected override void OnTextChanged(EventArgs e)
  {
      valueChanged = true;
      if(this.EditingControlDataGridView!=null)
        this.EditingControlDataGridView.NotifyCurrentCellDirty(true);        
      base.OnTextChanged(e);
  }



  public class CalendarColumn : DataGridViewColumn
  {
      public CalendarColumn()
          : base(new CalendarCell())
      {
      }

      public override DataGridViewCell CellTemplate
      {
          get
          {
              return base.CellTemplate;
          }
          set
          {
              // Ensure that the cell used for the template is a CalendarCell.
              if (value != null &&
                  !value.GetType().IsAssignableFrom(typeof(CalendarCell)))
              {
                  throw new InvalidCastException("Must be a CalendarCell");
              }
              base.CellTemplate = value;
          }
      }
  }

  public class CalendarCell : DataGridViewTextBoxCell
  {

      public CalendarCell()
          : base()
      {
          // Use the short date format.
          this.Style.Format = "d";
      }

      public override void InitializeEditingControl(int rowIndex, object
          initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)
      {
          // Set the value of the editing control to the current cell value.
          base.InitializeEditingControl(rowIndex, initialFormattedValue,
              dataGridViewCellStyle);
          CalendarEditingControl ctl =
              DataGridView.EditingControl as CalendarEditingControl;
          ctl.Value = (DateTime)this.Value;
      }

      public override Type EditType
      {
          get
          {
              // Return the type of the editing contol that CalendarCell uses.
              return typeof(CalendarEditingControl);
          }
      }

      public override Type ValueType
      {
          get
          {
              // Return the type of the value that CalendarCell contains.
              return typeof(DateTime);
          }
      }

      public override object DefaultNewRowValue
      {
          get
          {
              // Use the current date and time as the default value.
              return DateTime.Now;
          }
      }
  }

  class CalendarEditingControl : DateTimePicker, IDataGridViewEditingControl
  {
      DataGridView dataGridView;
      private bool valueChanged = false;
      int rowIndex;

      public CalendarEditingControl()
      {
          this.Format = DateTimePickerFormat.Short;
      }

      // Implements the IDataGridViewEditingControl.EditingControlFormattedValue 
      // property.
      public object EditingControlFormattedValue
      {
          get
          {
              return this.Value.ToShortDateString();
          }
          set
          {
              if (value is String)
              {
                  this.Value = DateTime.Parse((String)value);
              }
          }
      }

      // Implements the 
      // IDataGridViewEditingControl.GetEditingControlFormattedValue method.
      public object GetEditingControlFormattedValue(
          DataGridViewDataErrorContexts context)
      {
          return EditingControlFormattedValue;
      }

      // Implements the 
      // IDataGridViewEditingControl.ApplyCellStyleToEditingControl method.
      public void ApplyCellStyleToEditingControl(
          DataGridViewCellStyle dataGridViewCellStyle)
      {
          this.Font = dataGridViewCellStyle.Font;
          this.CalendarForeColor = dataGridViewCellStyle.ForeColor;
          this.CalendarMonthBackground = dataGridViewCellStyle.BackColor;
      }

      // Implements the IDataGridViewEditingControl.EditingControlRowIndex 
      // property.
      public int EditingControlRowIndex
      {
          get
          {
              return rowIndex;
          }
          set
          {
              rowIndex = value;
          }
      }

      // Implements the IDataGridViewEditingControl.EditingControlWantsInputKey 
      // method.
      public bool EditingControlWantsInputKey(
          Keys key, bool dataGridViewWantsInputKey)
      {
          // Let the DateTimePicker handle the keys listed.
          switch (key & Keys.KeyCode)
          {
              case Keys.Left:
              case Keys.Up:
              case Keys.Down:
              case Keys.Right:
              case Keys.Home:
              case Keys.End:
              case Keys.PageDown:
              case Keys.PageUp:
                  return true;
              default:
                  return false;
          }
      }

      // Implements the IDataGridViewEditingControl.PrepareEditingControlForEdit 
      // method.
      public void PrepareEditingControlForEdit(bool selectAll)
      {
          // No preparation needs to be done.
      }

      // Implements the IDataGridViewEditingControl
      // .RepositionEditingControlOnValueChange property.
      public bool RepositionEditingControlOnValueChange
      {
          get
          {
              return false;
          }
      }

      // Implements the IDataGridViewEditingControl
      // .EditingControlDataGridView property.
      public DataGridView EditingControlDataGridView
      {
          get
          {
              return dataGridView;
          }
          set
          {
              dataGridView = value;
          }
      }

      // Implements the IDataGridViewEditingControl
      // .EditingControlValueChanged property.
      public bool EditingControlValueChanged
      {
          get
          {
              return valueChanged;
          }
          set
          {
              valueChanged = value;
          }
      }

      // Implements the IDataGridViewEditingControl
      // .EditingPanelCursor property.
      public Cursor EditingPanelCursor
      {
          get
          {
              return base.Cursor;
          }
      }

      protected override void OnValueChanged(EventArgs eventargs)
      {
          // Notify the DataGridView that the contents of the cell
          // have changed.
          valueChanged = true;
          this.EditingControlDataGridView.NotifyCurrentCellDirty(true);
          base.OnValueChanged(eventargs);
      }
  }
}
#endregion

#region numericcolumn

public class NumericColumn : DataGridViewColumn
{
    public NumericColumn()
        : base(new NumericCell())
    {
    }

    public override DataGridViewCell CellTemplate
    {
        get
        {
            return base.CellTemplate;
        }
        set
        {
            // Ensure that the cell used for the template is a CalendarCell.
            if (value != null &&
                !value.GetType().IsAssignableFrom(typeof(NumericCell)))
            {
                throw new InvalidCastException("Must be a NumericCell");
            }
            base.CellTemplate = value;
        }
    }
}

public class NumericCell : DataGridViewTextBoxCell
{

    public NumericCell()
        : base()
    {
        // Use the short date format.
        //this.Style.Format = "";
    }

    public override void InitializeEditingControl(int rowIndex, object
        initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)
    {
        // Set the value of the editing control to the current cell value.
        base.InitializeEditingControl(rowIndex, initialFormattedValue,
            dataGridViewCellStyle);
        NumericEditingControl ctl =
            DataGridView.EditingControl as NumericEditingControl;
        ctl.Value = Convert.ToDecimal(this.Value);
    }

    public override Type EditType
    {
        get
        {
            // Return the type of the editing contol that CalendarCell uses.
            return typeof(NumericEditingControl);
        }
    }

    public override Type ValueType
    {
        get
        {
            // Return the type of the value that CalendarCell contains.
            return typeof(Decimal);
        }
    }

    public override object DefaultNewRowValue
    {
        get
        {
            // Use the current date and time as the default value.
            return 0;
        }
    }
}

class NumericEditingControl : NumericTextBox, IDataGridViewEditingControl
{
    DataGridView dataGridView;
    private bool valueChanged = false;
    int rowIndex;

    public NumericEditingControl()
    {
        
    }

    // Implements the IDataGridViewEditingControl.EditingControlFormattedValue 
    // property.
    public object EditingControlFormattedValue
    {
        get
        {
            return this.Value.ToString(this.Format);
        }
        set
        {
            if (value is decimal)
            {
                this.Value = Decimal.Parse((String)value);
            }
        }
    }

    // Implements the 
    // IDataGridViewEditingControl.GetEditingControlFormattedValue method.
    public object GetEditingControlFormattedValue(
        DataGridViewDataErrorContexts context)
    {
        return EditingControlFormattedValue;
    }

    // Implements the 
    // IDataGridViewEditingControl.ApplyCellStyleToEditingControl method.
    public void ApplyCellStyleToEditingControl(
        DataGridViewCellStyle dataGridViewCellStyle)
    {        
    }

    // Implements the IDataGridViewEditingControl.EditingControlRowIndex 
    // property.
    public int EditingControlRowIndex
    {
        get
        {
            return rowIndex;
        }
        set
        {
            rowIndex = value;
        }
    }

    // Implements the IDataGridViewEditingControl.EditingControlWantsInputKey 
    // method.
    public bool EditingControlWantsInputKey(
        Keys key, bool dataGridViewWantsInputKey)
    {
        // Let the DateTimePicker handle the keys listed.
        switch (key & Keys.KeyCode)
        {
            case Keys.Left:
            case Keys.Up:
            case Keys.Down:
            case Keys.Right:
            case Keys.Home:
            case Keys.End:
            case Keys.PageDown:
            case Keys.PageUp:
            case Keys.OemPeriod:
            case Keys.Decimal:                         
                return true;
            default:
                return false;
        }
    }

    // Implements the IDataGridViewEditingControl.PrepareEditingControlForEdit 
    // method.
    public void PrepareEditingControlForEdit(bool selectAll)
    {
        // No preparation needs to be done.
    }

    // Implements the IDataGridViewEditingControl
    // .RepositionEditingControlOnValueChange property.
    public bool RepositionEditingControlOnValueChange
    {
        get
        {
            return false;
        }
    }

    // Implements the IDataGridViewEditingControl
    // .EditingControlDataGridView property.
    public DataGridView EditingControlDataGridView
    {
        get
        {
            return dataGridView;
        }
        set
        {
            dataGridView = value;
        }
    }

    // Implements the IDataGridViewEditingControl
    // .EditingControlValueChanged property.
    public bool EditingControlValueChanged
    {
        get
        {
            return valueChanged;
        }
        set
        {
            valueChanged = value;
        }
    }

    // Implements the IDataGridViewEditingControl
    // .EditingPanelCursor property.
    public Cursor EditingPanelCursor
    {
        get
        {
            return base.Cursor;
        }
    }


    protected override void OnTextChanged(EventArgs e)
    {
        valueChanged = true;
        if(this.EditingControlDataGridView!=null)
            this.EditingControlDataGridView.NotifyCurrentCellDirty(true);
        base.OnTextChanged(e);
    }
}

#endregion
}
